Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Emulate @weak functions on Windows and don't emit COMDATs for ELF anymore #3424

Merged
merged 2 commits into from
May 17, 2020

Conversation

kinke
Copy link
Member

@kinke kinke commented May 7, 2020

The test adaptations are mostly a revert of 3893840.

@weak global variables are still left out but could be emulated exactly the same way.

@kinke
Copy link
Member Author

kinke commented May 7, 2020

I've looked into this because it might be a solution for #3158, at least for LDC - only emitting weak extern(C++) std::exception::what() etc. in druntime, so that they are ABI-compatible with the C++ ones and don't conflict with a potentially linked in C++ runtime.

@kinke kinke force-pushed the weak_msvc branch 2 times, most recently from 103a0ac to a5507cf Compare May 7, 2020 14:27
@kinke
Copy link
Member Author

kinke commented May 7, 2020

Is there any point in emitting Comdats for ELF? It prevents @weak from working properly (linker apparently prefers the version in the 1st object file, independent of whether it's weak or not), and clang doesn't emit them for Linux (well, for MSVC neither, but AFAIK, there the Comdats play the role of -f{function,data}-sections for linker stripping)...

@@ -27,7 +27,7 @@ extern (C)

void function() foo;

@weak // disable reasoning about this function
pragma(inline, false)
Copy link
Member

@JohanEngelen JohanEngelen May 7, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not do the same thing. What we want is the function to be opaque. Disabling inlining still allows IPO to learn about what is written to foo. I think the same holds for optStrategy(none).
Edit: but applied to the hot function it does not matter here because there indeed we don't want inlining.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just wanted to avoid additional complexity for string matching; for hot, disabling inlining wasn't enough, as the call was still elided. What worked was pragma(inline, false); llvm_sideeffect(); in the hot body, but optStrategy seemed nicer and had the same effect.

For select_func here, I thought disabling inlining would be enough (for string matching in the main body wrt. the foo function ptr); re-adding @weak wouldn't affect any strings though, and might even fix the regression with LLVM 4.0.

@kinke
Copy link
Member Author

kinke commented May 9, 2020

@rainers: Any suggestions wrt. how to 'best' adapt the mangled name (for backtrace/debugger/...)?

@rainers
Copy link
Contributor

rainers commented May 10, 2020

@rainers: Any suggestions wrt. how to 'best' adapt the mangled name (for backtrace/debugger/...)?

If you want it to be demangled with some modifications, prepending a package weak by changing the _D prefix to _D4weak should work.

Your use case in #3158 probably needs C++ symbols, though. VC mangling doesn't encode identifier length, so patching the first identifier might work, but it can be back referenced so it appears multiple times in the demangled name.

@kinke kinke changed the title Windows: Add proper emulation for @weak functions Add proper emulation for @weak functions and Windows targets, and don't emit COMDATs for ELF anymore May 15, 2020
@kinke kinke changed the title Add proper emulation for @weak functions and Windows targets, and don't emit COMDATs for ELF anymore Emulate @weak functions on Windows and don't emit COMDATs for ELF anymore May 15, 2020
@kinke kinke marked this pull request as ready for review May 15, 2020 18:20
@kinke
Copy link
Member Author

kinke commented May 15, 2020

Cleaned up & put a little more effort into the renamed mangle.

clang emits COMDATs for templates and inline functions only (with linkonce_odr), not for regular functions, for both MSVC and Linux targets. I have no idea whether ELF COMDATs provide any benefit and so whether I should try harder and only get rid of them for regular functions, to make @weak work properly.

@JohanEngelen
Copy link
Member

You could ask on the forums about the COMDATs on Linux, but I doubt you'll get useful feedback.
If Clang does not emit it, then I think it is fairly safe to omit them.

@kinke
Copy link
Member Author

kinke commented May 15, 2020

Yeah I wanted to know if you guys know more about this, otherwise I'd propose to include this in the upcoming beta and see how it goes.

@kinke
Copy link
Member Author

kinke commented May 15, 2020

Interestingly, the produced static libraries are now noticeably smaller for the Azure Linux x64 job (compared against latest master run):

  • libdruntime-ldc.a: 2,898 vs. 3,210 KB (-9.7%)
  • libphobos2-ldc.a: 9,466 vs. 10,393 KB (-8.9%)

The shared libs are minimally larger:

  • libdruntime-ldc-shared.so: 1,625 vs. 1,619 KB
  • libphobos2-ldc-shared.so: 6,202 vs. 6,173 KB (+0.5%)

if (lwc.second)
obj->setComdat(gIR->module.getOrInsertComdat(obj->getName()));
obj->setComdat(lwc.second ? gIR->module.getOrInsertComdat(obj->getName())
: nullptr);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW, I've also tried setting the COMDAT's selection kind to 'exact match' (instead of 'any'), but that only led back to the multiple definition errors.

…more

Emulation for @weak global variables is still left out but should be
analogous.

The test adaptations are mostly a revert of 3893840. The testcase has
shown that @weak hasn't worked properly for ELF (linker apparently
prefers the version in the 1st object file, independent of whether it's
weak or not), because the functions are emitted in COMDATs.
clang emits COMDATs for templates and inline functions only, not for
regular functions.
@JohanEngelen
Copy link
Member

I just found out that the ELF COMDAT change is causing trouble at Weka. It prevents merging of symbols, leaving excess data around in a section where Weka's tooling wants there to be no garbage (or well, it just exceeds the amount of data that the system can deal with (ushort...)). Re-enabling COMDAT fixes it.
I guess we have to start doing what @kinke noted about clang (I think that would fix Weka's problem):

clang emits COMDATs for templates and inline functions only (with linkonce_odr), not for regular functions,

I'll work on a small testcase, so you can see what the problem is.

@JohanEngelen
Copy link
Member

Opened an issue for it with testcase: #3589

@JohanEngelen
Copy link
Member

LLVM 11 release notes:
"Windows target: Produce COFF weak external symbols for IR level weak symbols without a comdat (e.g. for attribute((weak)) in C)"
https://releases.llvm.org/11.0.0/docs/ReleaseNotes.html#changes-to-the-windows-target

@kinke Does that remove the need for the "emulation" of this PR ?

@kinke
Copy link
Member Author

kinke commented Oct 23, 2020

I've read that, found it a nice conincidence, but haven't tested whether it works similar to this manual emulation here. Anyway, it's not restricted to LLVM11+, and we always emit comdats on Windows.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants